﻿''' <summary>
''' 組織単位リスト画面のフォームです。
''' </summary>
''' <remarks></remarks>
Friend NotInheritable Class OUList

#Region " プライベートフィールド "
  Private ReadOnly ouCol As List(Of OrganizationalUnit)   'OUのコレクション
#End Region

#Region " パブリックコンストラクター "
  ''' <summary>
  ''' OUList クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <remarks></remarks>
  Public Sub New()
    ' この呼び出しはデザイナーで必要です。
    InitializeComponent()
    ' InitializeComponent() 呼び出しの後で初期化を追加します。

    Dim ous = DirectoryAccess.GetOrganizationalUnits()  'OUを取得
    ouCol = ous.OrderBy(Function(ou) ou.DisplayPath).ThenBy(Function(ou) ou.Name).ToList()
    Me.OUBindingSource.DataSource = ouCol
    Me.CountLabel.Text = String.Format("{0} 個のオブジェクト", Me.OUBindingSource.Count)
    Me.AddChildNode(Nothing)  '子ノードを追加
    Me.OUTreeView.ExpandAll()
  End Sub
#End Region

#Region " イベントハンドラ "
  Private Sub OUTreeView_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles OUTreeView.AfterSelect
    Dim selectedOU = ouCol.Single(Function(ou) ou.Entry.Path.Equals(e.Node.Tag.ToString()))
    Me.OUBindingSource.Position = Me.OUBindingSource.IndexOf(selectedOU)
    Me.ShowStoredData(selectedOU)   '格納されているデータを表示
  End Sub
#End Region

#Region " プライベートメソッド "
  ''' <summary>
  ''' 子ノードを追加します。
  ''' </summary>
  ''' <param name="node">子ノードを追加するノード。</param>
  ''' <remarks></remarks>
  Private Sub AddChildNode(node As TreeNode)
    Dim path = If(node Is Nothing, String.Empty, node.FullPath)
    Dim childOUs = ouCol.Where(Function(ou) ou.DisplayPath.Equals(path)).ToList()   '直下のOU

    For Each ou In childOUs
      Dim childNode = CreateNode(ou)  'ノードを作成
      If node Is Nothing Then
        Me.OUTreeView.Nodes.Add(childNode)
      Else
        node.Nodes.Add(childNode)
      End If
      Me.AddChildNode(childNode)  '子ノードを追加
    Next
  End Sub

  ''' <summary>
  ''' 指定した OU のノードを作成します。
  ''' </summary>
  ''' <param name="ou">OU。</param>
  ''' <returns>作成したノード。</returns>
  ''' <remarks></remarks>
  Private Function CreateNode(ou As OrganizationalUnit) As TreeNode
    Dim path = If(ou.DisplayPath.Length = 0, String.Empty, ou.DisplayPath & "/")
    Return New TreeNode(ou.Name) With {.Name = path & ou.Name, .Tag = ou.Entry.Path}
  End Function

  ''' <summary>
  ''' 指定した OU に格納されているデータを表示します。
  ''' </summary>
  ''' <param name="ou">OU。</param>
  ''' <remarks></remarks>
  Private Sub ShowStoredData(ou As OrganizationalUnit)
    Dim subItem(2) As String    '名前と種類と説明の配列
    Me.DataListView.Items.Clear()
    For Each domainObject In ou.StoredDomainObjects   '直下のオブジェクト数分
      Dim objectType = DirectCast([Enum].Parse(GetType(CategoryType), domainObject.Entry.SchemaClassName, True), CategoryType)
      subItem(0) = domainObject.Name  '名前をセット
      subItem(1) = DirectoryAccess.CategoryNames.Item(objectType)   '種類をセット
      subItem(2) = domainObject.Description   '説明をセット
      Me.DataListView.Items.Add(New ListViewItem(subItem, objectType))
    Next
    Me.DataCountLabel.Text = String.Format("{0} 個のオブジェクト", ou.StoredDomainObjects.Count)
  End Sub
#End Region
End Class